:- module(standard_page, [standard_page/5, standard_page_nb/3], 
        [
            pillow,
            assertions,
            isomodes
        ]).


:- comment(title, "Generating Standard Pages for Amos").
:- comment(author, "Manuel Carro").
:- comment(version, "0.0").
:- comment(subtitle, "Amos Project").
:- comment(copyright, "(C) 2003 The Clip Group").

:- comment(summary, "A set of utils to automate the generation of web
pages having a similar look.  Navigation bars and links between the
pages are defined separately from the actual contents of the pages.").

:- comment(module, "The programs and data files in this directory
define the general appearance of an Amos page and some of its
contents, namely those which can be decided in a semi-statical
fashion.  This page generation scheme allows a program to generate a
page by giving:

@begin{itemize}
@item An identifier (an atom) which univoquely denotes the page, and
@item The contens (the body) of the page.
@end{itemize}

The title and navigation bar (including text and links) of every page
are stated using separate predicates (which now live in different
modules).  Ancillary modules to define useful predicates are also
provided.


@subsection{How a Page is Defined}

A page is defined by an identifier which appears as the first argument
in @pred{page_data/4} (now in module @file{page_definitions}).  This
predicate can provide also the title (which can be passed or not to
@pred{standard_page/5}.  It is also possible to define where a page
should end up, in order to @bf{recalculate} automatically all the
links between the project pages.  The page location can have the
following forms:

@begin{itemize} 

@item An atom @pred{add_to_root}, which means that the page identifier
is prepended the @tt{.html} suffix to compose the file name of the
page, and is supposed to be placed in the root of WWW installation.

@item An atom @pred{add_to_cgi}, which means that the page identifier
is prepended the @tt{.cgi} suffix to compose the name of the CGI, and
is supposed to be placed in the CGI-bin directory.

@item A structure @pred{root_relative/1} which has a string as
argument and which is taken as a file/path name to be appended to the
root of the WWW installation.

@item A structure @pred{cgi_relative/1} which has a string as argument
and which is taken as a file/path name to be appended to the root of
the CGI bin.

@end{itemize}


The navigation bar is referred to with an identifier stored as fourth
argument.  A separate identifier is used because several pages can
have the same navigation bar.  Only the topmost box of the navigatiorn
bar is mutable (this is defined in the module @file{standard_page}).  Boxes
are defined in the module @file{boxes}, and each box has: an indentifier
(referred to by the page identifier), a box title (a string), and a
list of identifiers per item appearing in each box.  The information
associated to each of these identifiers (i.e., text and link) is in
the module @file{links}.

That module contains, for each identifier which can be expanded, the
string to be shown and a representatino of the URL where it should
point to.  This URL can be a string, and then it is taken as is
(either absolute or relative) or a structure of the form
@pred{link_page(where_to)}, where @pred{where_to} should be the
identifier of a page as stated in the module @file{page_definition}.
Then, (internal) links are automatically generated and associated to
the text.  A structure of the form @pred{link_page(where_to, label)}
can also be used to denote an HTML @tt{label} inside the @tt{where_to}
page.  If the argument of a @pred{link_page/1} structure (or the first
argument of a @pred{link_page/2}) is not found, an error is reported
when trying to use it.  The second argument of @pred{link_page/2} is
not checked (it is instead used verbatim).


@subsection{Where is This Used}

The predicates in these files, and the others in the modules used by
this one, are used to generate standard-looking pages from short,
readable descriptions.  It is being used in Amos:

@begin{itemize}

@item From the search CGIs: the CGI generates code for the body to be
displayed, decides which page it is in, and generates the whole page
by calling @pred{standard_page/5} with the appropriate title and
sidebox name.

@item To generate the @em{static pages} whose bodies are stored in
this directory: the body of the page is read and the file name
(without the @tt{.html} suffix) is used as page identifier.

@item To generate a single page template for WebDB.
@end{itemize}
").

:- use_module(library(lists), [append/3]).
:- use_module(library('pillow/pillow_types')).

:- use_module(amos(configuration), [css_url/1]).
:- use_module(portalfiles(page_pieces), [amos_top_logo/1]).

:- use_module(portalfiles(web_utils), [generate_box/2]).

:- use_module(portalfiles(get_page_info), [
        page_def/4,
        resolve_link/2
                                          ]).


% This predicate defines the layout of a page: an HTML header,
% a text header, a left sidebox, and a central part with the contents.
% The topmost part of the left widebox depends on the page, and it is
% thus passed as a parameter.

:- pred standard_page(+Type, +Title, +SideBox, +Body, -HTML) :
        atom * string * term * html_term * canonic_html_term #

"This predicate constructs a web page using PiLLoW terms.  The general
structure of the page is expressed in this predicate, and therefore
only its basic components need to be defined: @var{Title} is a string
with the title of the page; @var{SideBox} is a pillow term with the
contents of the topmost box of the navigation bar (the other two boxes
are fixed); @var{Body} is a PiLLoW term with the actual contents of
the page, and @var{HTML} is a PiLLoW structure where all the code is
returned.  Depending on the value of @var{Type}, a page with @tt{all},
the components, or a page with only the @tt{navigation} bar, or a page
with only the @tt{header} title is returned.".


standard_page(Type, Title, PerPageSB, BodyText, HTML):-

        HTML = [
                  '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',

		   env(html, 
                    [xmlns="http://www.w3.org/1999/xhtml"], 
                    [nl, nl, 
                     HeadHTML, 
                     nl, nl, 
                     env(body, [], 
                     [
                         TopMenuHTML,
                         env(div, [id="bodyText"], [BodyText]),
                         env(div, [id="sideBar"], [LeftBarHTML])
                     ])
                    ])],
        standard_head(Title, HeadHTML),
        (
            (Type = header ; Type = all) ->
            topmenu(Title, TopMenuHTML)
        ;
            TopMenuHTML = []
        ),
        (
            (Type = navigation ; Type = all) ->
             generic_sidebox(GenericSB),
             leftbar([PerPageSB|GenericSB], LeftBarHTML)
        ;
            LeftBarHTML = []
        ).

standard_page_nb(Type, Title, HTML):-
        HTML = [env(html, 
                    ['xml:lang'="en"], 
                    [nl, nl, 
                     HeadHTML, 
                     nl, nl, 
                     env(body, [], 
                     [
                         TopMenuHTML
                     ])
                    ])],
        standard_head(Title, HeadHTML),
        (
            (Type = header ; Type = all) ->
            topmenu(Title, TopMenuHTML)
        ;
            TopMenuHTML = []
        ).


          
generic_sidebox([S1,S2]):-
        generate_box(box_standard_upper, S1),
        generate_box(box_standard_lower, S2).

% HTML file header, including the links to the CSS style sheets

standard_head(Title, [HeadHTML]):-
        HeadHTML = env(head, [], [nl, CSS, nl, env(title, [], [Title]), nl]),
        amos_css_style(CSS).

% Links to access the CSS.  css_url/1 is in a file automatically generated 
% at compilation/installation time.

amos_css_style([Style]):-
        Style = [
                    elem(link,[rel="stylesheet",
                               type="text/css",
                               href=AmosStyle,
                               title="AMOS stylesheet"])],
        css_url(CssUrl),
        atom_codes(CssUrl, CssUrlStr),
        append(CssUrlStr, "/amos.css", AmosStyle).

%% This predicate handles the generation of the (fixed) header. 

topmenu(Title, HTML):-
        HTML = [
                   nl,nl,
                  TitleAndTopNavigation,
                   nl,nl
               ],
	amos_top_logo(AmosLogo),
        TitleAndTopNavigation =
                   env(div, [id="header"],
		   [
		       env(div,[style="float:right;"],[AmosLogo]),
                       env(div,[class="menuBar"],
		       [
			   env(div,[class="headerTitle"], [Title]),
			   env(div,[],[
			   env(a,[href=ProjectHome],["Start"]),
			   " | ", nl,
			   env(a,[href=Information],["Information"]),
			   " | ", nl,
			   env(a,[href=Search],["Search"]),
			   " | ", nl,
			   env(a,[href=Describe],["Describe"]),
			   " | ", nl,
			   env(a,[href=Administration],["Administration"])])
		      ]),
		      nl
		   ]),
        url_data(ProjectHome, Information, Search, Describe, Administration).
               

url_data(ProjectHome, Information, Search, Describe, Administration):-
%        ProjectHome = "http://www.amosproject.org/",
        page_def(index, _, ProjectHome, _),
        page_def(information, _, Information, _),
        page_def(match, _, Search, _),
        page_def(description, _, Describe, _),
        page_def(administration, _, Administration, _).

leftbar([E|Es], [EHTML|EHTMLS]):-
        EHTML = env(div, [class="topSideBox LHS"], [E]),
        leftbar_(Es, EHTMLS).

leftbar_([], []).
leftbar_([E|Es], [EHTML|EHTMLS]):-
        EHTML = env(div, [class="sideBox LHS"], [E]),
        leftbar_(Es, EHTMLS).

